Skip to contentMethod: static {...}
1: /*
2: * *********************************************************************************************************************
3: *
4: * Mistral: open source imaging engine
5: * http://tidalwave.it/projects/mistral
6: *
7: * Copyright (C) 2003 - 2023 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *********************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
12: * the License. You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
17: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
18: * specific language governing permissions and limitations under the License.
19: *
20: * *********************************************************************************************************************
21: *
22: * git clone https://bitbucket.org/tidalwave/mistral-src
23: * git clone https://github.com/tidalwave-it/mistral-src
24: *
25: * *********************************************************************************************************************
26: */
27: package it.tidalwave.image.metadata.loader;
28:
29: import javax.annotation.Nonnull;
30: import java.util.ArrayList;
31: import java.util.Collection;
32: import java.util.List;
33: import java.util.Optional;
34: import java.io.IOException;
35: import java.io.InputStream;
36: import javax.imageio.ImageReader;
37: import javax.imageio.metadata.IIOMetadata;
38: import javax.imageio.stream.ImageInputStream;
39: import com.drew.imaging.ImageMetadataReader;
40: import com.drew.imaging.ImageProcessingException;
41: import com.drew.metadata.Metadata;
42: import com.drew.metadata.exif.ExifIFD0Directory;
43: import com.drew.metadata.exif.ExifSubIFDDirectory;
44: import com.drew.metadata.iptc.IptcDirectory;
45: import com.drew.metadata.xmp.XmpDirectory;
46: import lombok.RequiredArgsConstructor;
47: import lombok.extern.slf4j.Slf4j;
48:
49: /***********************************************************************************************************************
50: *
51: * @author Fabrizio Giudici
52: *
53: **********************************************************************************************************************/
54: @Slf4j
55: public class JpegDrewMetadataLoader implements MetadataLoader
56: {
57: @Nonnull
58: private final Metadata metadata;
59:
60: /*******************************************************************************************************************
61: *
62: ******************************************************************************************************************/
63: @RequiredArgsConstructor
64: static class InputStreamAdapter extends InputStream
65: {
66: @Nonnull
67: private final ImageInputStream iis;
68:
69: @Override
70: public int available()
71: throws IOException
72: {
73: var l = (int)iis.length(); // sometimes returns -1 and getDirectory() fails
74: return l < 0 ? Integer.MAX_VALUE : l;
75: }
76:
77: @Override
78: public int read()
79: throws IOException
80: {
81: return iis.read();
82: }
83: }
84:
85: /*******************************************************************************************************************
86: *
87: ******************************************************************************************************************/
88: public JpegDrewMetadataLoader (@Nonnull final ImageReader reader)
89: {
90: try
91: {
92: final var iis = (ImageInputStream)reader.getInput();
93: final var pos = iis.getStreamPosition();
94: iis.seek(0);
95: final var is = new InputStreamAdapter(iis);
96: metadata = ImageMetadataReader.readMetadata(is);
97:
98: // OTHER DIRECTORIES: JPEG JFIF
99: /*
100: for (var directory : metadata.getDirectories())
101: {
102: for (var tag : directory.getTags())
103: {
104: log.debug("[{}] - {} = {}",
105: directory.getName(), tag.getTagName(), tag.getDescription());
106: }
107: if (directory.hasErrors())
108: {
109: for (var error : directory.getErrors())
110: {
111: log.warn("ERROR: {}", error);
112: }
113: }
114: }
115: */
116:
117: iis.seek(pos);
118: }
119: catch (IOException | ImageProcessingException e)
120: {
121: throw new RuntimeException(e);
122: }
123: }
124:
125: /*******************************************************************************************************************
126: * {@inheritDoc}
127: ******************************************************************************************************************/
128: @Override @Nonnull
129: public Optional<DirectoryLoader> getTiffLoader (@Nonnull final IIOMetadata iioMetadata)
130: {
131: return Optional.of(new DirectoryDrewLoader(list(metadata.getDirectoriesOfType(ExifIFD0Directory.class)), 0));
132: }
133:
134: /*******************************************************************************************************************
135: * {@inheritDoc}
136: ******************************************************************************************************************/
137: @Override @Nonnull
138: public Optional<DirectoryLoader> getExifLoader (@Nonnull final IIOMetadata iioMetadata)
139: {
140: return Optional.of(new DirectoryDrewLoader(list(metadata.getDirectoriesOfType(ExifSubIFDDirectory.class)), 0));
141: }
142:
143: /*******************************************************************************************************************
144: * {@inheritDoc}
145: ******************************************************************************************************************/
146: @Override @Nonnull
147: public Optional<DirectoryLoader> getIptcLoader (@Nonnull final IIOMetadata iioMetadata)
148: {
149: return Optional.of(new DirectoryDrewLoader(list(metadata.getDirectoriesOfType(IptcDirectory.class)), 0));
150: }
151:
152: /*******************************************************************************************************************
153: * {@inheritDoc}
154: ******************************************************************************************************************/
155: @Override @Nonnull
156: public Optional<DirectoryLoader> getXmpLoader (@Nonnull final IIOMetadata iioMetadata)
157: {
158: return Optional.of(new DirectoryDrewLoader(list(metadata.getDirectoriesOfType(XmpDirectory.class)), 0));
159: }
160:
161: /*******************************************************************************************************************
162: *
163: ******************************************************************************************************************/
164: @Nonnull
165: private static <T> List<T> list (@Nonnull final Collection<T> collection)
166: {
167: return new ArrayList<>(collection);
168: }
169: }